package com.ycorn.auth.config;

import com.ycorn.auth.util.SystemConstant;
import lombok.AllArgsConstructor;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.savedrequest.HttpSessionRequestCache;
import org.springframework.security.web.savedrequest.RequestCache;
import org.springframework.security.web.savedrequest.SavedRequest;

import java.io.PrintWriter;

@EnableWebSecurity
@Configuration
@AllArgsConstructor
@EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    private final CacheManager cacheManager;

    @Bean
    public PasswordEncoder passwordEncoder() {
        // 明文解密
        return new BCryptPasswordEncoder();
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable()
                .authorizeRequests()
                .antMatchers("/r/r1").hasAnyAuthority("p1")
                .antMatchers("/r/r2").hasAnyAuthority("p2")
                .antMatchers("/r/**").authenticated()
                .anyRequest().permitAll()
                .and()
                .formLogin()
                .loginPage("/login-view")
                .loginProcessingUrl("/login")
                .successHandler((request, response, authentication) -> {
                    // 登录成功之后返回访问的页面
                    response.setContentType(MediaType.APPLICATION_JSON_VALUE);
                    PrintWriter writer = response.getWriter();
                    RequestCache cache = new HttpSessionRequestCache();
                    SavedRequest savedRequest = cache.getRequest(request, response);
                    if (null != savedRequest) {
                        String url = savedRequest.getRedirectUrl();
                        response.sendRedirect(url);
                    } else {
                        writer.write("login success");
                        writer.flush();
                    }
                })
                .failureHandler((request, response, exception) -> {
                    response.setContentType(MediaType.APPLICATION_JSON_VALUE);
                    PrintWriter writer = response.getWriter();
                    writer.write("login failure");
                    writer.flush();
                })
                .and()
                .logout()
                .logoutSuccessHandler((request, response, authentication) -> {
                    // 登出 删除cache
                    Cache cache = cacheManager.getCache(SystemConstant.USER_DETAIL_CACHE_KEY);
                    if (null != cache && null != authentication) {
                        cache.evict(((UserDetails) authentication.getPrincipal()).getUsername());
                    }
                });
    }
}